home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include "defs.h"
-
- #define DEFAULT 0
- #define ENHANCED 1
- #define MANUAL 2
- #define SYMMETRIC 3
-
- ypedef struct {
- int **image;
- short xsize, ysize;
- int nflag, spos, sneg;
- } FILTER;
-
- har *progname;
- har *filename;
- ixrect *pr1, *pr2;
- nt scale_method;
- loat scale;
- nt offset;
- har *filtername;
- hort max_enhanced = -32768, min_enhanced = 32767;
- nt mfx, mfy;
- nt levels;
- FILTER *filter;
-
- #ifdef STANDALONE
- ain(argc, argv, envp)
- #else
- onvolve_main(argc, argv, envp)
- #endif
- int argc;
- char **argv;
- char **envp;
- {
- register int i, j;
- FILTER *loadfilter();
-
- scale_method = DEFAULT;
- scale = 1.;
- offset = 0;
- filtername = strsave("non-specified");
- progname = strsave(argv[0]);
- parse_profile(&argc, argv, envp);
-
- while ((gc = getopt(argc, argv, "sef:lm:M:")) != EOF)
- switch (gc) {
- case 's':
- scale_method = SYMMETRIC;
- break;
- case 'e':
- scale_method = ENHANCED;
- break;
- case 'f':
- filtername = strsave(optarg);
- break;
- case 'l':
- execlp("ls", "ls", "-C", FILTERS_DIR, 0);
- exit();
- break;
- case 'm':
- scale_method = MANUAL;
- scale = atof(optarg);
- break;
- case 'M':
- scale_method = MANUAL;
- offset = (int) atof(optarg);
- break;
- case '?':
- errflag++;
- break;
- }
-
- if (errflag)
- error((char *) 0, "Usage: %s: [-e] [-s] [-f filter] [-l] [-m manual_scale] [-M manual_offset] [infile] [outfile]", progname);
-
- for (stream = 0; optind < argc; stream++, optind++)
- if (stream < 2 && strcmp(argv[optind], "-") != 0)
- if (freopen(argv[optind], mode[stream], f[stream]) == NULL)
- error("%s %s", PR_IO_ERR_INFILE, argv[optind]);
-
- filter = loadfilter(filtername);
-
- if ((pr1 = pr_load(stdin, NULL)) == NULL)
- error(PR_IO_ERR_RASREAD);
-
- if (bitrestrict)
- levels = calc_max(pr1)+1;
- else
- levels = MAXLEVEL(pr1->pr_depth);
-
- if ((pr2 = mem_create(pr1->pr_size.x, pr1->pr_size.y, pr1->pr_depth)) == NULL)
- error("mem_create returned NULL");
-
- mfx = filter->xsize / 2;
- mfy = filter->ysize / 2;
-
- switch (scale_method) {
- case DEFAULT:
- calc_default_scale();
- one_pass();
- break;
- case ENHANCED:
- case SYMMETRIC:
- two_pass();
- break;
- case MANUAL:
- one_pass();
- break;
- }
-
- pr_dump(pr2, stdout, NULL, RT_STANDARD, 0);
- }
-
- FILTER *
- oadfilter(name)
- char *name;
- {
- char buf[BUFSIZ];
- FILE *fp;
- char *ep;
- FILTER *filter;
- int xsize, ysize, ival;
- register int i, j;
- char *getenv();
-
- if ((ep = getenv("FILTERS")) == NULL)
- strcpy(buf, FILTERS_DIR);
- else
- strcpy(buf, ep);
-
- strcat(buf, "/");
- strcat(buf, name);
-
- if (!(fp = fopen(buf, "r")))
- error("Couldn't open filter %s", name);
-
- fscanf(fp, "%d %d", &xsize, &ysize);
- filter = (FILTER *) malloc(sizeof(FILTER));
- filter->image = (int **) dynamem(&(filter->image), sizeof(int), 2, ysize, xsize);
-
- filter->nflag = FALSE;
- filter->xsize = xsize;
- filter->ysize = ysize;
-
- for (j = 0; j < ysize; j++)
- for (i = 0; i < xsize; i++) {
- fscanf(fp, "%d", &ival);
- filter->image[j][i] = ival;
- if (ival < 0) {
- filter->nflag = TRUE;
- filter->sneg += ival;
- } else
- filter->spos += ival;
- }
- filter->sneg = abs(filter->sneg);
-
- return filter;
- }
- alc_default_scale()
- {
- if (filter->nflag) {
- scale = (float) levels / (float) (MAX(filter->spos, filter->sneg) * 2);
- offset = levels / 2;
- } else {
- scale = (float) levels / (float) (MAX(filter->spos, filter->sneg));
- offset = 0;
- }
- }
- ne_pass()
- {
- register int total;
- register int fj, fi;
- register int i, j;
-
- warning("scale = %g on input, offset = %d on output", scale, offset);
-
- for (j = 0; j < pr1->pr_size.y - filter->ysize; j++)
- for (i = 0; i < pr1->pr_size.x - filter->xsize; i++) {
- total = 0;
- for (fj = 0; fj < filter->ysize; fj++)
- for (fi = 0; fi < filter->xsize; fi++)
- total += (pr_get(pr1, i + fi, j + fj) * filter->image[fj][fi]);
- pr_put(pr2, i + mfx, j + mfy, truncate((int) ((float) total * scale) + offset, levels, 0));
- }
- }
- wo_pass()
- {
- register int total;
- register int least, most;
- register int fj, fi;
- register int i, j;
- int tmppix;
- Pixrect *tmp;
-
- if ((tmp = mem_create(pr1->pr_size.x, pr1->pr_size.y, 32)) == NULL)
- error("mem_create returned NULL");
-
- /* first pass */
- least = 32768;
- most -= 32767;
- for (j = 0; j < pr1->pr_size.y - filter->ysize; j++)
- for (i = 0; i < pr1->pr_size.x - filter->xsize; i++) {
- total = 0;
- for (fj = 0; fj < filter->ysize; fj++)
- for (fi = 0; fi < filter->xsize; fi++)
- total += (pr_get(pr1, i + fi, j + fj) * filter->image[fj][fi]);
- pr_put(tmp, i + mfx, j + mfy, total);
- least = MIN(total, least);
- most = MAX(total, most);
- }
- least = abs(least);
-
- /* calculate scale and offset */
- if (scale_method == SYMMETRIC) {
- scale = (float) levels / (float) (MAX(least, most) * 2);
- scale /= (filter->nflag) ? 2. : 1.;
- offset = (filter->nflag) ? levels / 2 : 0;
- } else { /* enhanced */
- scale = (float) levels / (float) (least + most);
- offset = (filter->nflag) ? least * scale : 0;
- }
-
- warning("scale = %g on filter, output offset = %d on output", scale, offset);
-
- /* second pass */
- for (j = 0; j < pr1->pr_size.y - filter->ysize; j++)
- for (i = 0; i < pr1->pr_size.x - filter->xsize; i++) {
- tmppix = truncate((int) ((float) pr_get(tmp, i, j) * scale + offset), levels, 0);
- pr_put(pr2, i, j, tmppix);
- }
- }
-